<!-- AnimateComponent.vue -->
<script setup lang="ts">
import {computed, onMounted, ref} from "vue";
import type AnimateProp from "@/components/animate/type/AnimateProp.ts";

const $prop = withDefaults(defineProps<AnimateProp>(), {
  type: 'bounce',
  easing: 'ease',
  origin: 'left top',
  duration: 250,
  delay: 0
})

const isAnimating = ref(false)
const animateRef = ref<HTMLElement>()

// 计算内联样式
const containerStyle = computed(() => ({
  transformOrigin: $prop.origin,
  transition: `all ${$prop.duration}ms ${$prop.easing}`,
  transitionDelay: `${$prop.delay}ms`,
  transform: isAnimating.value ? 'scale(1)' : 'scale(0)',
  opacity: isAnimating.value ? 1 : 0
}))

// 计算动画样式（用于keyframes动画）
const animationStyle = computed(() => {
  if (!isAnimating.value) return {}

  const animationName = getAnimationName($prop.type)
  return {
    animation: `${animationName} ${$prop.duration}ms ${$prop.easing} ${$prop.delay}ms forwards`
  }
})

// 获取动画名称
const getAnimationName = (type: string) => {
  switch (type) {
    case 'bounce':
      return 'bounceIn'
    case 'fade':
      return 'fadeIn'
    case 'slide':
      return 'slideIn'
    default:
      return 'bounceIn'
  }
}

onMounted(() => {
  // 确保DOM已渲染，然后添加延迟
  setTimeout(() => {
    isAnimating.value = true
  }, $prop.delay)
})

</script>

<template>
  <div
      ref="animateRef"
      class="animate-container"
      :class="{ 'is-animating': isAnimating }"
      :style="$prop.type === 'scale' ? containerStyle : { ...containerStyle, ...animationStyle }"
      @click="isAnimating = !isAnimating">
    <slot/>
  </div>
</template>

<style scoped>
.animate-container {
  display: inline-block;
}

/* 动画关键帧 */
@keyframes bounceIn {
  0% {
    transform: scale(0);
    opacity: 0;
  }
  50% {
    transform: scale(1.1);
    opacity: 0.8;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes fadeIn {
  0% {
    transform: scale(0.8);
    opacity: 0;
  }
  100% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes slideIn {
  0% {
    transform: scale(0) translateX(-20px);
    opacity: 0;
  }
  100% {
    transform: scale(1) translateX(0);
    opacity: 1;
  }
}
</style>